local oo = require("SharedLibs.BaseLib");
local co = require("SharedLibs.CoroLib");


AsyncOp = require("SharedLibs.AsyncOp");
AsyncOpState = require("SharedLibs.AsyncOpState");


--[[
封装一个异步环境下的call/cc

example:
	local ccCo = g.run(function()
		warn("start function_A");
		
		warn("let's delay 1 sec");
		g.delay(1);

		warn("Before callcc");
		local ret = g.callcc(function(cc)
			warn("this is function_B, let's delay 1 sec!");
			g.delay(1);
			warn("good work, let jump back to function_A and return value 'hahaha'");
			cc("hahaha");
			
			g.delay(1);
			warn("will not executed here!");
		end)

		warn("callcc's return is: "..ret);
	end)

	g.run(function()
		g.delay(0.5);
		warn("Pause callcc");
		ccCo:Pause();
		g.InputMgr.keyDown:Wait();
		warn("Resume callcc");
		ccCo:Resume();
	end)
]]
CallCC = oo.Class()
CallCC.name = "CallCC"
oo.ClassExtends(CallCC, AsyncOp)

--- func: Continuation
function co.CallCC(func)
	local op = oo.New(CallCC, func);
	return co.yield(op);
end

--- func: Continuation
function co.NewCallCC(func) 
	return oo.New(CallCC, func);
end

function CallCC.prototype.constructor(self, func)
	CallCC._ss.prototype.constructor(self)

	self._state = AsyncOpState.Ready
	self._func = func;

	--- 用来执行异步执行func的co
	self._funcCo = nil;

	--- cc is current continuation
	self._cc = function(retVal)
		self._returnValue = retVal;
		
		self:_doStop(true);
	end
end

function CallCC.prototype:GetReturn()
	return self._returnValue
end

function CallCC.prototype:_onStart()
	assert(not self._funcCo);

	self._funcCo = co.New(self._func, self._cc);
	self._funcCo:OnComplete(function(retVal)
		self._returnValue = retVal;
		self:_doStop(true);
	end);
	self._funcCo:Start();
end

function CallCC.prototype:_onStop()
	self._funcCo:Stop();
	self._funcCo = nil;

end

function CallCC.prototype:_onPause()
	self._funcCo:Pause();
end

function CallCC.prototype:_onResume()
	self._funcCo:Resume();
end

function CallCC.prototype:_onReset()
	self._funcCo:Stop();
	self._funcCo = nil;
end

return CallCC;
